﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Windows.Forms;
using CloudShot.Utils;

namespace CloudShot.ViewModels
{
  //TODO refactor check box preview. almost same classes
  internal class RadioButtonPropertyHandler<T> : PropertyHandlerBase<T>, IPropertiesControlGroup, IPropertyHolder<RadioButton, T>
  {
    private readonly bool _hasPreviewByHover;
    //TODO use same interface with CheckBox IPropertiesControlGroup->IPropertyHandler
    private readonly List<ControlHoverHandler<RadioButton, T>> _hoverHandlers = new List<ControlHoverHandler<RadioButton, T>>();
    public event EventHandler CloseRequest;
    public event EventHandler PreviewRequest;


    public RadioButtonPropertyHandler(Expression<Func<PropertiesFormViewModel, T>> expression, bool hasPreviewByHover = true) 
      : base(expression.GetPropertyInfo())
    {
      _hasPreviewByHover = hasPreviewByHover;
    }

    public void Add(RadioButton control, T value)
    {
      _hoverHandlers.Add(new ControlHoverHandler<RadioButton, T>(control, this, value));
    }

    protected virtual void PreviewInternal(T previewValue)
    {
      if (!_hasPreviewByHover)
        return;

      //Debug.WriteLine(string.Format("***PreviewInternal value {0}", previewValue));

      CurrentPreviewValue = previewValue;
      PropertyInfo.SetValue(ViewModel, previewValue, null);
      InvokeRefreshRequest(ViewModel);
    }

    protected virtual void ResetInternal()
    {
      if (!_hasPreviewByHover)
        return;

      //Debug.WriteLine(string.Format("***ResetInternal value {0}", InitialValue));
      CurrentPreviewValue = InitialValue;
      PropertyInfo.SetValue(ViewModel, InitialValue, null);
      InvokeRefreshRequest(ViewModel);
    }

    protected virtual void SetPropertyInternal(T value)
    {
      InitialValue = value;
      //Debug.WriteLine(string.Format("***SetPropertyInternal value {0}, new Initial {1}", value, InitialValue));
      PropertyInfo.SetValue(ViewModel, value, null);
      InvokeCloseRequest(ViewModel);
    }

    protected override void UpdateButtons(T value)
    {
      foreach (var pair in _hoverHandlers)
      {
        pair.Control.Checked = pair.PropertyValue.Equals(value);
      }
    }

    protected override void InvokeRefreshRequest(PropertiesFormViewModel viewModel)
    {
      EventHandler handler = PreviewRequest;
      if (handler != null)
        handler(viewModel, EventArgs.Empty);
    }

    private void InvokeCloseRequest(PropertiesFormViewModel viewModel)
    {
      EventHandler handler = CloseRequest;
      if (handler != null)
        handler(viewModel, EventArgs.Empty);
    }

    #region IPropertyHolder<RadioButton, T> Implementation

    void IPropertyHolder<RadioButton, T>.PreviewProperty(RadioButton control, T previewValue)
    {
      if (ViewModel == null)
        return;

      PreviewInternal(previewValue);
    }

    void IPropertyHolder<RadioButton, T>.ResetPreviewProperty(RadioButton control)
    {
      if (ViewModel == null)
        return;

      ResetInternal();
    }

    void IPropertyHolder<RadioButton, T>.SetProperty(RadioButton control, T value)
    {
      if (ViewModel == null)
        return;

      SetPropertyInternal(value);
    }

    #endregion
  }
}